"""
图片处理工具类，提供图片旋转、亮度调整、RGB调整、添加内容等操作
"""

import os
from typing import Tuple, Union

try:
    from PIL import Image, ImageEnhance, ImageDraw, ImageFont
    PIL_AVAILABLE = True
except ImportError:
    PIL_AVAILABLE = False
    print("警告: Pillow库未安装，图片处理功能将不可用。请运行: pip install Pillow")


class ImageUtils:
    """
    图片处理工具类，提供各种图片处理功能
    """
    
    def __init__(self, image_path: str = None):
        """
        初始化图片处理工具

        :param image_path: 图片路径，可选
        """
        if not PIL_AVAILABLE:
            raise Exception("Pillow库不可用，请安装Pillow库")
        
        self.image = None
        if image_path:
            self.load_image(image_path)
    
    def load_image(self, image_path: str) -> None:
        """
        加载图片

        :param image_path: 图片路径
        """
        if not os.path.exists(image_path):
            raise FileNotFoundError(f"图片文件不存在: {image_path}")
        self.image = Image.open(image_path)
    
    def save_image(self, save_path: str, format: str = None) -> None:
        """
        保存图片

        :param save_path: 保存路径
        :param format: 图片格式，如'JPEG', 'PNG'等
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image.save(save_path, format=format)
    
    def rotate_center(self, angle: float, expand: bool = True) -> None:
        """
        图片中心旋转

        :param angle: 旋转角度（度）
        :param expand: 是否扩展画布以适应旋转后的图片
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.rotate(angle, expand=expand)
    
    def adjust_brightness(self, factor: float) -> None:
        """
        调整图片亮度

        :param factor: 亮度因子，1.0为原始亮度，小于1.0变暗，大于1.0变亮
        """
        if self.image is None:
            raise Exception("没有加载图片")
        enhancer = ImageEnhance.Brightness(self.image)
        self.image = enhancer.enhance(factor)
    
    def adjust_contrast(self, factor: float) -> None:
        """
        调整图片对比度

        :param factor: 对比度因子，1.0为原始对比度，小于1.0降低对比度，大于1.0增强对比度
        """
        if self.image is None:
            raise Exception("没有加载图片")
        enhancer = ImageEnhance.Contrast(self.image)
        self.image = enhancer.enhance(factor)
    
    def adjust_color(self, factor: float) -> None:
        """
        调整图片色彩饱和度

        :param factor: 色彩因子，1.0为原始色彩，小于1.0降低色彩饱和度，大于1.0增强色彩饱和度
        """
        if self.image is None:
            raise Exception("没有加载图片")
        enhancer = ImageEnhance.Color(self.image)
        self.image = enhancer.enhance(factor)
    
    def adjust_sharpness(self, factor: float) -> None:
        """
        调整图片锐度

        :param factor: 锐度因子，1.0为原始锐度，小于1.0降低锐度，大于1.0增强锐度
        """
        if self.image is None:
            raise Exception("没有加载图片")
        enhancer = ImageEnhance.Sharpness(self.image)
        self.image = enhancer.enhance(factor)
    
    def resize(self, size: Tuple[int, int], resample=Image.LANCZOS) -> None:
        """
        调整图片大小

        :param size: 新的尺寸 (宽度, 高度)
        :param resample: 重采样算法
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.resize(size, resample=resample)
    
    def crop(self, box: Tuple[int, int, int, int]) -> None:
        """
        裁剪图片

        :param box: 裁剪区域 (左, 上, 右, 下)
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.crop(box)
    
    def add_text(self, text: str, position: Tuple[int, int], 
                 font_path: str = None, font_size: int = 20, 
                 color: Union[str, Tuple[int, int, int]] = "white") -> None:
        """
        在图片上添加文字

        :param text: 要添加的文字
        :param position: 文字位置 (x, y)
        :param font_path: 字体文件路径，可选
        :param font_size: 字体大小
        :param color: 文字颜色
        """
        if self.image is None:
            raise Exception("没有加载图片")
        
        # 创建绘图对象
        draw = ImageDraw.Draw(self.image)
        
        # 加载字体
        try:
            if font_path and os.path.exists(font_path):
                font = ImageFont.truetype(font_path, font_size)
            else:
                font = ImageFont.load_default()
        except:
            font = ImageFont.load_default()
        
        # 添加文字
        draw.text(position, text, fill=color, font=font)
    
    def add_rectangle(self, box: Tuple[int, int, int, int], 
                      outline: Union[str, Tuple[int, int, int]] = "red", 
                      width: int = 1, fill: Union[str, Tuple[int, int, int]] = None) -> None:
        """
        在图片上绘制矩形

        :param box: 矩形区域 (左, 上, 右, 下)
        :param outline: 边框颜色
        :param width: 边框宽度
        :param fill: 填充颜色
        """
        if self.image is None:
            raise Exception("没有加载图片")
        
        draw = ImageDraw.Draw(self.image)
        draw.rectangle(box, fill=fill, outline=outline, width=width)
    
    def add_ellipse(self, box: Tuple[int, int, int, int], 
                    outline: Union[str, Tuple[int, int, int]] = "red", 
                    width: int = 1, fill: Union[str, Tuple[int, int, int]] = None) -> None:
        """
        在图片上绘制椭圆

        :param box: 椭圆外切矩形区域 (左, 上, 右, 下)
        :param outline: 边框颜色
        :param width: 边框宽度
        :param fill: 填充颜色
        """
        if self.image is None:
            raise Exception("没有加载图片")
        
        draw = ImageDraw.Draw(self.image)
        draw.ellipse(box, fill=fill, outline=outline, width=width)
    
    def add_line(self, xy: Tuple[int, int, int, int], 
                 fill: Union[str, Tuple[int, int, int]] = "red", 
                 width: int = 1) -> None:
        """
        在图片上绘制直线

        :param xy: 直线坐标 (x1, y1, x2, y2)
        :param fill: 线条颜色
        :param width: 线条宽度
        """
        if self.image is None:
            raise Exception("没有加载图片")
        
        draw = ImageDraw.Draw(self.image)
        draw.line(xy, fill=fill, width=width)
    
    def flip_horizontal(self) -> None:
        """
        水平翻转图片
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.transpose(Image.FLIP_LEFT_RIGHT)
    
    def flip_vertical(self) -> None:
        """
        垂直翻转图片
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.transpose(Image.FLIP_TOP_BOTTOM)
    
    def convert_mode(self, mode: str) -> None:
        """
        转换图片模式

        :param mode: 目标模式，如'RGB', 'L'(灰度), 'RGBA'等
        """
        if self.image is None:
            raise Exception("没有加载图片")
        self.image = self.image.convert(mode)
    
    def get_image_info(self) -> dict:
        """
        获取图片信息

        :return: 图片信息字典
        """
        if self.image is None:
            raise Exception("没有加载图片")
        
        return {
            'size': self.image.size,
            'mode': self.image.mode,
            'format': self.image.format,
            'width': self.image.width,
            'height': self.image.height
        }
    
    @staticmethod
    def create_blank_image(size: Tuple[int, int], 
                          color: Union[str, Tuple[int, int, int]] = 'white') -> 'ImageUtils':
        """
        创建空白图片

        :param size: 图片尺寸 (宽度, 高度)
        :param color: 背景颜色
        :return: ImageUtils实例
        """
        if not PIL_AVAILABLE:
            raise Exception("Pillow库不可用，请安装Pillow库")
        
        img_utils = ImageUtils()
        img_utils.image = Image.new('RGB', size, color)
        return img_utils
    
    @staticmethod
    def merge_images(images: list, direction: str = 'horizontal') -> 'ImageUtils':
        """
        合并多张图片

        :param images: ImageUtils实例列表
        :param direction: 合并方向 'horizontal' 或 'vertical'
        :return: 合并后的ImageUtils实例
        """
        if not images:
            raise Exception("图片列表不能为空")
        
        if not PIL_AVAILABLE:
            raise Exception("Pillow库不可用，请安装Pillow库")
        
        # 获取所有图片
        pil_images = [img.image for img in images if img.image is not None]
        if not pil_images:
            raise Exception("没有有效的图片")
        
        if direction == 'horizontal':
            # 水平合并
            total_width = sum(img.width for img in pil_images)
            max_height = max(img.height for img in pil_images)
            
            merged_image = Image.new('RGB', (total_width, max_height))
            
            x_offset = 0
            for img in pil_images:
                merged_image.paste(img, (x_offset, 0))
                x_offset += img.width
        else:
            # 垂直合并
            max_width = max(img.width for img in pil_images)
            total_height = sum(img.height for img in pil_images)
            
            merged_image = Image.new('RGB', (max_width, total_height))
            
            y_offset = 0
            for img in pil_images:
                merged_image.paste(img, (0, y_offset))
                y_offset += img.height
        
        # 创建新的ImageUtils实例
        img_utils = ImageUtils()
        img_utils.image = merged_image
        return img_utils